﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.Contract.ContractPcon;
using HamcoWcs.Contract.ContractSrm;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.MesMsgQueues;
using HamcoWcs.Entitys.WcsLocations;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.DeviceMsgs;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Service.Common;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Xml;

namespace HamcoWcs.Service.Mes.Parsers
{
    /// <summary>
    /// MES获取托盘信息
    /// </summary>
    public class MesMsgParser_TransportJobListRequest : MesMsgParserBase
    {
        public override void HandleEvent(MesMsgQueue message)
        {
            var res = message.Content;
            res = XmlHelper.SetXmlNodeText(res, "MESSAGENAME", "TransportJobListReply");
            res = XmlHelper.SetXmlNodeText(res, "REPLYSUBJECTNAME", TibcoConfiguration.BasicConfiguration.RecvSubject);
            var doc = new XmlDocument();
            doc.LoadXml(res);

            try
            {
                var jobNodes = doc.SelectNodes("//TRANSPORTJOB")
                    ?? throw new MESJobException(201, "TRANSPORTJOBLIST is null");
                if (jobNodes.Count == 0)
                    throw new MESJobException(201, "TRANSPORTJOBLIST is null");

                var tasks = _wcsDbContext.MainTasks.AsNoTracking().ToList();
                for (int i = 0; i < jobNodes.Count; i++)
                {
                    var node = jobNodes[i];
                    var unitId = node.SelectSingleNode("//PALLETNAME")?.InnerText ?? "";
                    var jobName = node.SelectSingleNode("//TRANSPORTJOBNAME")?.InnerText ?? "";

                    if (!jobName.Contains(unitId))
                        throw new MESJobException(202, "Error TRANSPORTJOB");

                    if (string.IsNullOrEmpty(unitId) || string.IsNullOrEmpty(jobName))
                        throw new MESJobException(202, "Error TRANSPORTJOB");

                    var t = tasks.Any(x => x.UnitId == unitId);

                    var r = doc.CreateElement("WCSCHECKRESULT");


                  
                    var WCSCHECKRESULT = t ? "Y" : "N";
                    SetNewNode(doc, node, "WCSCHECKRESULT", WCSCHECKRESULT);
                    var address = GetPalletPosition(unitId);

                    if (address != null)
                    {
                        SetNewNode(doc, node, "CURRENTMACHINENAME", address.CURRENTMACHINENAME);
                        SetNewNode(doc, node, "CURRENTPOSITIONTYPE", address.CURRENTPOSITIONTYPE);
                        SetNewNode(doc, node, "CURRENTPOSITIONNAME", address.CURRENTPOSITIONNAME);
                        SetNewNode(doc, node, "CURRENTZONENAME", address.CURRENTZONENAME);
                    }
                }
                message.Return = XmlHelper.XmlDocumentToString(doc);
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
            }
            catch (MESJobException ex)
            {
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                var r = XmlHelper.XmlDocumentToString(doc);
                r = XmlHelper.SetNGReturn(r,ex.ErrorCode.ToString(),ex.Message);
                message.Return = r;
            }
            catch (Exception ex)
            {
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                var r = XmlHelper.XmlDocumentToString(doc);
                r = XmlHelper.SetNGReturn(r, "7", "Unknown exception");
                message.Return = r;
            }
            _wcsDbContext.SaveChanges();
        }



        private void SetNewNode(XmlDocument doc, XmlNode node, string subNodeName, string value)
        {
            var sNode = node.SelectSingleNode($"//{subNodeName}");
            if (sNode is null)
            {
                sNode = doc.CreateElement(subNodeName);
                node.AppendChild(sNode);
            }

            sNode.InnerText = value;
        }

        private CurrentAddress GetPalletPosition(string unitId)
        {
            var loc = _locationService.GetPalletLocation(unitId);

            if (loc != null)
            {
                return new CurrentAddress()
                {
                    CURRENTMACHINENAME = loc.Aisle,
                    CURRENTPOSITIONNAME = loc.WcsLocName,
                    CURRENTPOSITIONTYPE = "SHELF",
                    CURRENTZONENAME = loc.ZoneName
                };
            }

            var con = _asrs.Pcons.FirstOrDefault(x => x.UnitId == unitId);

            if (con != null)
            {
                return new CurrentAddress()
                {
                    CURRENTMACHINENAME = con.MachineName,
                    CURRENTPOSITIONNAME = con.PortName,
                    CURRENTPOSITIONTYPE = "PORT",
                    CURRENTZONENAME = ""
                };
            }

            var srm = _asrs.Srms.FirstOrDefault(x => x.UnitId == unitId);
            if (srm != null)
            {
                return new CurrentAddress()
                {
                    CURRENTMACHINENAME = srm.MachineName,
                    CURRENTPOSITIONNAME = srm.PortName,
                    CURRENTPOSITIONTYPE = "PORT",
                    CURRENTZONENAME = ""
                };
            }

            return null;
        }

        private readonly IMesCommunicateService _mesCommunicateService;
        private readonly ILocationService _locationService;
        private readonly IPconBaseService _pconService;
        private readonly IBaseSrmTaskService _srmService;
        private readonly AutomaticStorageInfo _asrs;
        public MesMsgParser_TransportJobListRequest(ILoggerService loggerService, WcsDbContext wcsDbContext, IMapper mapper, IMesCommunicateService mesCommunicateService, ILocationService locationService,
            IPconBaseService pconService, IBaseSrmTaskService srmService, AutomaticStorageInfo asrs) : base(loggerService, wcsDbContext, mapper)
        {
            _pconService = pconService;
            _srmService = srmService;
            _mesCommunicateService = mesCommunicateService;
            _locationService = locationService;
            _asrs = asrs;
        }

        public override string EventName => "TransportJobListRequest";
    }


    public class CurrentAddress
    {
        public string CURRENTMACHINENAME { get; set; }
        public string CURRENTPOSITIONTYPE { get; set; }
        public string CURRENTPOSITIONNAME { get; set; }
        public string CURRENTZONENAME { get; set; }
    }
}
